#include "event/loop.hpp"
#include "fmt/core.h"
#include "network/sockaddr.hpp"
#include "network/stdio_stream.hpp"
#include "network/tcp_acceptor.hpp"
#include "network/tcp_connection.hpp"

#include <set>
#include <string_view>

using namespace std;
using namespace ibox::event;
using namespace ibox::network;
int main() {
    SockAddr bind_addr = SockAddr::from_string("127.0.0.1:8080");
    auto loop = Loop();

    set<TcpConnection *> conns;
    // 读取服务端的输入, 广播到所有的连接上
    StdioStream stdio{&loop};
    stdio.set_receive_callback(
        [&](Buffer &buff) {
            for (auto *conn : conns) {
                conn->send(buff.readable_begin(), buff.readable_size());
            }
            buff.has_readall();
        },
        0);
    stdio.enable();

    // 这个例子中是用的TcpAcceptor, 不是TcpServer管理Connection,
    // 所以有手动管理Tcp连接的步骤
    TcpAcceptor acceptor{&loop};
    acceptor.initialize(bind_addr, 3);
    acceptor.set_new_connection_callback([&](TcpConnection *new_conn) {
        new_conn->set_disconnected_callback([=]() { delete new_conn; });
        new_conn->bind(new_conn); // 信息流绑定为自己
        conns.insert(new_conn);   // 将自己注册到 conns 中
    });
    acceptor.start();

    if (bind_addr.type() == SockAddr::Type::IPv4) {
        IpAddress ip;
        uint16_t port = 0;
        bind_addr.get(ip, port);
        cout << "try command: nc " << ip.to_string() << ' ' << port << '\n';
    }
    loop.run();
}
